<?php

namespace app\common\services;

use app\common\model\User;
use app\common\model\PrivateMessage as PrivateMessageModel;
use app\common\model\payload\Payload;
use app\common\model\payload\Check as CheckPayload;

/**
 * 用法(New PrivateMessage())->with($payload)->send('正文')->to($user);
 * 用法(New PrivateMessage())->with($payload)->send('正文')->toAll();
 */
class PrivateMessage
{
    const TYPE_NONE = 'null';

    protected $message_type;
    protected $from;
    protected $content;
    protected $payload;

    public function __construct($from = null)
    {
        if ($from === null) {
            $from = getCurrentUser();
        }
        $this->from = $from;

        $this->message_type = self::TYPE_NONE;
        $this->payload = [];
    }

    public function with($payload)
    {
        if (is_array($payload)) {
            $this->message_type = self::TYPE_NONE;
            $this->payload = $payload;
        } else if ($payload instanceof Payload) {
            $payloadClassName = get_class($payload);
            preg_match('/(\w+)$/', $payloadClassName, $matches);
            $this->message_type = $matches[1];
            $this->payload = $payload->jsonSerialize();
        } else {
            error('服务器内部异常，payload无效');
        }

        return $this;
    }

    public function send($content)
    {
        $this->content = $content;
        return $this;
    }

    public function to(User $to)
    {
        $message = new PrivateMessageModel();
        $message->message_type = $this->message_type;
        $message->to_id = $to->id;
        $message->from_id = $this->from->id;
        $message->content = $this->content;
        $message->payload = $this->payload;
        $message->is_read = false;
        $message->save();
        return $this;
    }

    public function toAll()
    {
        $users = User::where(1)->select();
        db()->transaction(function () use ($users) {
            foreach ($users as $user) {
                /** @var User $user */
                $this->to($user);
            }
        });
    }
}
